/*
 * rwBlocks.c
 *
 *  Created on: 27/11/2011
 *      Author: utn_so
 */

#include "rwBlocks.h"
#include "structsFAT.h"
#include "direccionamiento.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include "socketMng.h"
#include "../../General/Serializable/serializable.h"

int32_t rwBlocks_sizeofSector;

int writeBlock(BLOQUE aBloque, char * buffer)
{
	int Result = 0;
	FIFO_SECTOR aSectorList;
	Nodo_SECTOR * aux;
	char * newData;
	int32_t offset = 0,
			i;

	newData = (char *)calloc(SizeOfBloque, sizeof(char));
	memcpy(newData, buffer, SizeOfBloque);
	FIFO_SECTOR_Create(&aSectorList);

	mapBloqueToSectors(aBloque, &aSectorList);
	aux = aSectorList.Head;

	Message aMsg;
	Serializable_t aSerializable;
	SOCKET aSocket;
	char response[128];

	aSocket = SocketMNG_getConnection();

	while (aux != NULL) {
		aMsg.type = msgWrite;
		aMsg.sectorRequest = aux->sector;
		aMsg.contentSize = rwBlocks_sizeofSector;
		aMsg.content = newData + offset;
		Serialize_Message(&aSerializable, aMsg);
		Result = send(aSocket, aSerializable.Data, aSerializable.Size, 0);
		Serializable_Free(&aSerializable);
		offset += rwBlocks_sizeofSector;
		aux = aux->nxt;
	}
	for (i = 0; i < sectoresPorBloque; i++)
		recv(aSocket, response, HeaderSize, 0); //Falta manejar la respuesta, igualmente no aporta mucho
	SocketMNG_closeConnection(aSocket);

	FIFO_SECTOR_Destroy(&aSectorList);
	free(newData);
	return Result;
}

int readBlock(BLOQUE aBloque, int32_t ReadBytes, char * outStream)
{
	FIFO_SECTOR aSectorList;
	Nodo_SECTOR * aux;
	int32_t Result = 0,
			i;

	FIFO_SECTOR_Create(&aSectorList);
	mapBloqueToSectors(aBloque, &aSectorList);
	aux = aSectorList.Head;

	Message aMsg;
	Serializable_t aSerializable;
	SOCKET aSocket;
	char response[128];

	aSocket = SocketMNG_getConnection();

	while (aux != NULL) {
		aMsg.type = msgRead;
		aMsg.sectorRequest = aux->sector;
		aMsg.contentSize = 0;
		aMsg.content = NULL;
		Serialize_Message(&aSerializable, aMsg);
		Result = send(aSocket, aSerializable.Data, aSerializable.Size, 0);
		Serializable_Free(&aSerializable);
		aux = aux->nxt;
	}
	for(i = 0; i < sectoresPorBloque; i++) {
		recv(aSocket, response, HeaderSize, MSG_WAITALL);
		if (aSectorList.Head->sector == getSectorFromHeader(response)) //es el primer sector
			recv(aSocket, outStream, getSizeFromHeader(response), MSG_WAITALL);
		else
			recv(aSocket, outStream + rwBlocks_sizeofSector, getSizeFromHeader(response), MSG_WAITALL);
	}
	SocketMNG_closeConnection(aSocket);

	FIFO_SECTOR_Destroy(&aSectorList);
	return Result;
}

void rwBlocks_SetSizeOfSector(int32_t size)
{
	rwBlocks_sizeofSector = size;
}
